{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "import lightgbm as lgb\n",
    "import xgboost as xgb\n",
    "from sklearn.preprocessing import LabelEncoder,OneHotEncoder\n",
    "from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer,HashingVectorizer\n",
    "from sklearn.decomposition import TruncatedSVD,SparsePCA\n",
    "from sklearn.model_selection import KFold,StratifiedKFold\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import accuracy_score,roc_auc_score,f1_score,recall_score\n",
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "import gc\n",
    "import time\n",
    "import os\n",
    "import sys\n",
    "import warning\n",
    "\n",
    "pickle_path = \"../pickle\"\n",
    "\n",
    "train = pd.read_csv(\"../data/age_train.csv\",names=['uid','age_group']).sort_values(by=['uid'])\n",
    "test = pd.read_csv(\"../data/age_test.csv\",names=['uid']).sort_values(by=['uid'])\n",
    "info = pd.read_csv(\"../data/app_info.csv\",names=['appid','category'])\n",
    "active = pd.read_pickle(\"{}/user_app_active_flatten.pickle\".format(pickle_path))\n",
    "# usage = pd.read_pickle(\"{}/user_app_usage.pickle\".format(pickle_path))\n",
    "user_basic_info = pd.read_csv(\"../data/user_basic_info.csv\",names=['uid','gender','city','prodname','ramcapacity','ramleftration','romcapacity','romleftration','color','fontsize','ct','carrier','os']).sort_values(by=['uid'])\n",
    "behavior_info = pd.read_csv(\"../data/user_behavior_info.csv\",names=['uid','boottimes','a','b','c','d','e','f','g']).sort_values(by=['uid'])\n",
    "print((train.shape,test.shape),(info.shape,active.shape,user_basic_info.shape,behavior_info.shape,usage.shape))\n",
    "\n",
    "all_data = train.append(test)\n",
    "all_data = all_data.sort_values(by=['uid']).reset_index(drop=True)\n",
    "print(all_data.shape)\n",
    "\n",
    "for i in tqdm(user_basic_info.select_dtypes('object').columns):\n",
    "    lbl = LabelEncoder()\n",
    "    user_basic_info[i] = lbl.fit_transform(user_basic_info[i].astype('str')) \n",
    "\n",
    "appid = LabelEncoder()\n",
    "active['appid'] = appid.fit_transform(active['appid'])\n",
    "\n",
    "active = active.merge(behavior_info,how='left',on='uid').merge(user_basic_info,how='left',on='uid')\n",
    "print(active.head())\n",
    "\n",
    "active['uid_appid_count'] = active[['uid','appid']].groupby(['uid'])['appid'].transform('count')\n",
    "active['uid_appid_std'] = active[['uid','appid']].groupby(['uid'])['appid'].transform('std')\n",
    "\n",
    "active['appid_uid_count'] = active[['uid','appid']].groupby(['appid'])['uid'].transform('count')\n",
    "active['appid_uid_std'] = active[['uid','appid']].groupby(['appid'])['uid'].transform('std')\n",
    "\n",
    "active['uid_fontsize_std'] = active[['uid','fontsize']].groupby(['uid'])['fontsize'].transform('std')\n",
    "active['uid_fontsize_mean'] = active[['uid','fontsize']].groupby(['uid'])['fontsize'].transform('mean')\n",
    "\n",
    "def reduce_mem_usage(df, verbose=True):\n",
    "    numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']\n",
    "    start_mem = df.memory_usage().sum() / 1024**2    \n",
    "    for col in df.columns:\n",
    "        col_type = df[col].dtypes\n",
    "        if col_type in numerics:\n",
    "            c_min = df[col].min()\n",
    "            c_max = df[col].max()\n",
    "            if str(col_type)[:3] == 'int':\n",
    "                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n",
    "                    df[col] = df[col].astype(np.int8)\n",
    "                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n",
    "                    df[col] = df[col].astype(np.int16)\n",
    "                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n",
    "                    df[col] = df[col].astype(np.int32)\n",
    "                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n",
    "                    df[col] = df[col].astype(np.int64)  \n",
    "            else:\n",
    "                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n",
    "                    df[col] = df[col].astype(np.float16)\n",
    "                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n",
    "                    df[col] = df[col].astype(np.float32)\n",
    "                else:\n",
    "                    df[col] = df[col].astype(np.float64)    \n",
    "    end_mem = df.memory_usage().sum() / 1024**2\n",
    "    if verbose: print('Mem. usage decreased to {:5.2f} Mb ({:.1f}% reduction)'.format(end_mem, 100 * (start_mem - end_mem) / start_mem))\n",
    "    return df\n",
    "\n",
    "active = reduce_mem_usage(active)\n",
    "\n",
    "from sklearn.model_selection import KFold,StratifiedKFold,GroupKFold,RepeatedKFold\n",
    "\n",
    "def rmse(y_true, y_pred):\n",
    "    return (mean_squared_error(y_true, y_pred))** .5\n",
    "\n",
    "# use df_hist_train df_new_train df_hist_new_train to train 3 models\n",
    "train_df = active[active['age_group'].notnull()]\n",
    "test_df = active[active['age_group'].isnull()]\n",
    "\n",
    "drop_features = ['age_group', 'uid',]\n",
    "cat_features = ['appid'] \n",
    "\n",
    "feats = [f for f in active.columns if f not in drop_features]\n",
    "\n",
    "n_splits= 3\n",
    "folds = GroupKFold(n_splits=n_splits)\n",
    "oof_preds = np.zeros(train_df.shape[0])\n",
    "sub_preds = np.zeros(test_df.shape[0])\n",
    "\n",
    "print ('feats:' + str(len(feats)))\n",
    "\n",
    "for n_fold, (train_idx, valid_idx) in enumerate(folds.split(train_df[feats], train_df['age_group'],groups=train_df['uid'])):\n",
    "    train_x, train_y = train_df[feats].iloc[train_idx], train_df['age_group'].iloc[train_idx]\n",
    "    valid_x, valid_y = train_df[feats].iloc[valid_idx], train_df['age_group'].iloc[valid_idx] \n",
    "    \n",
    "    print(\"Train Index:\",train_idx,\",Val Index:\",valid_idx)\n",
    "\n",
    "    params = {\n",
    "               \"objective\" : \"regression\", \n",
    "               \"boosting\" : \"gbdt\", \n",
    "               \"metric\" : \"rmse\",  \n",
    "               \"max_depth\": 7, \n",
    "               \"num_leaves\" : 31, \n",
    "               \"max_bin\" : 255, \n",
    "               \"learning_rate\" : 0.1, \n",
    "               \"subsample\" : 0.8,\n",
    "               \"colsample_bytree\" : 0.8, \n",
    "               \"verbosity\": -1,\n",
    "               \"num_threads\" : 40,\n",
    "    }\n",
    "    \n",
    "\n",
    "    if n_fold >= 0:\n",
    "        evals_result = {}\n",
    "        dtrain = lgb.Dataset(\n",
    "            train_x, label=train_y,categorical_feature=cat_features)\n",
    "        dval = lgb.Dataset(\n",
    "            valid_x, label=valid_y, reference=dtrain,categorical_feature=cat_features)\n",
    "        bst = lgb.train(\n",
    "            params, dtrain, num_boost_round=30000,\n",
    "            valid_sets=[dval], early_stopping_rounds=100, verbose_eval=20,)#feval = evalerror\n",
    "        \n",
    "        new_list = sorted(zip(feats, bst.feature_importance('gain')),key=lambda x: x[1], reverse=True)[:]\n",
    "        for item in new_list:\n",
    "            print (item) \n",
    "\n",
    "        oof_preds[valid_idx] = bst.predict(valid_x, num_iteration=bst.best_iteration)\n",
    "\n",
    "        sub_preds += bst.predict(test_df[feats], num_iteration=bst.best_iteration) / folds.n_splits # test_df_new\n",
    "\n",
    "cv = rmse(train_df['age_group'],  oof_preds)\n",
    "print('Full OOF RMSE %.6f' % cv)  \n",
    "\n",
    "a = train_df[['uid']]\n",
    "b = test_df[['uid']]\n",
    "\n",
    "a['age_pred'] = oof_preds\n",
    "b['age_pred'] = sub_preds\n",
    "\n",
    "a1 = a.groupby(['uid'])['age_pred'].agg(['mean','std','min','max','median','skew'])\n",
    "b1 = b.groupby(['uid'])['age_pred'].agg(['mean','std','min','max','median','skew'])\n",
    "\n",
    "a1.append(b1).add_prefix(\"active_GROUPKFOLD_agg_pred_\").reset_index().sort_values(by=['uid']).reset_index(drop=True).to_pickle(\"../pickle/Meta_active_GROUP_Regeress.pickle\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
